package org.sachiew;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

public class MyKshell {
    // (degree,{nodes})
    private HashMap<Integer, HashSet<String>> kshellMap = new HashMap<Integer, HashSet<String>>();
    private int K = 9999;// 当前K值
    private int LastK = 0;// 保留前一次K值

    public void cluster(HashMap<String, HashSet<String>> networksHashMap) {
        while (networksHashMap.size() != 0) {
            /**
             * The Lowest Degree（K） 寻找合理最小度最为K值
             */
            for (String e : networksHashMap.keySet()) {
                if (networksHashMap.get(e).size() <= K) {
                    K = networksHashMap.get(e).size();
                }
            }
            if (K < LastK) {
                K = LastK;
            }

            // System.out.println("当前在 " + K + " shell 中");

            if (!kshellMap.containsKey(K)) {
                kshellMap.put(K, new HashSet<String>());
            }

            /**
             * 聚类节点至K-shell collection; 条件:残余度小于等于K值（合理最小度）
             */
            for (String mainPoint : networksHashMap.keySet()) {
                if (networksHashMap.get(mainPoint).size() <= K) {
                    kshellMap.get(K).add(mainPoint);
                }
            }

            /**
             * 处理网络（删除已脱离节点的相关通路）
             */
            if (kshellMap.get(K).size() == 0) {
                kshellMap.remove(K);// 网络中残留节点的残余度均大于K，此K-shell中未有相应节点
            } else {
                Iterator<String> detachedPointIterator = kshellMap.get(K).iterator();
                // 遍历k-shell map中主节点
                while (detachedPointIterator.hasNext()) {
                    String detachedPoint = detachedPointIterator.next();// tmp ：主节点
                    // 删除边缘节点（附加节点）与已分离节点（主节点）的通路
                    // System.out.println(detachedPoint);// 909-313---
                    // k-shell map中包含《前一遍已从网络中detach的点 | 刚刚归入k-shell ！还未detach的点》需加以区分避免空指针
                    if (networksHashMap.containsKey(detachedPoint)) {
                        Iterator<String> edgePointIterator = networksHashMap.get(detachedPoint).iterator();// 得到通路另一端的边缘节点
                        while (edgePointIterator.hasNext()) {
                            networksHashMap.get(edgePointIterator.next()).remove(detachedPoint);// 移除已分离节点与边缘节点的通路
                        }
                    }

                    // 删除主节点
                    networksHashMap.remove(detachedPoint);
                }
            }

            /**
             * 收尾处理
             */
            LastK = K;
            K++;
        }
    }

    public void displayClusterStatus() {
        for (Integer key : kshellMap.keySet()) {
            System.out.println("------------ " + key + " - shell ------------");
            System.out.println(kshellMap.get(key) + "\n");
            // Iterator<String> nodeIterator = kshellMap.get(key).iterator();
            // while (nodeIterator.hasNext()) {
            // System.out.print(nodeIterator.next() + " ");
            // }
            // System.out.println();
        }
        System.out.println();
    }

    public HashMap<Integer, HashSet<String>> getKshellMap() {
        return kshellMap;
    }
}